Several page allocations, done in the hypervisor when starting an HVM
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Fri, 19 May 2006 15:10:52 +0000 (16:10 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Fri, 19 May 2006 15:10:52 +0000 (16:10 +0100)
domain, are not checked.  This can cause the physical machine to crash
when starting the HVM domain during low-memory conditions.

Kudos to Charles Arnold for catching the problem with
shadow_direct_map_init.

Signed-off-by: Charles Coffing <ccoffing@novell.com>
xen/arch/x86/hvm/hvm.c
xen/arch/x86/hvm/svm/svm.c
xen/arch/x86/hvm/svm/vmcb.c

index e5a3c89703a371bad29ca5e87079c3b529a50231..a0844e4edf035dd344e9f3750cd26922d224d207 100644 (file)
@@ -189,7 +189,11 @@ void hvm_setup_platform(struct domain* d)
     if ( !hvm_guest(current) || (current->vcpu_id != 0) )
         return;
 
-    shadow_direct_map_init(d);
+    if ( shadow_direct_map_init(d) == 0 )
+    {
+        printk("Can not allocate shadow direct map for HVM domain.\n");
+        domain_crash_synchronous();
+    }
 
     hvm_map_io_shared_page(d);
     hvm_get_info(d);
index 2541a140f95aced88be7d89d60c2ad6f6e7f7b9f..96e0d31b7f6dcc3129611af9ae77e5c72bd911f6 100644 (file)
@@ -458,6 +458,9 @@ int start_svm(void)
     
     if (!(test_bit(X86_FEATURE_SVME, &boot_cpu_data.x86_capability)))
         return 0;
+    svm_globals[cpu].hsa = alloc_host_save_area();
+    if (! svm_globals[cpu].hsa)
+        return 0;
     
     rdmsr(MSR_EFER, eax, edx);
     eax |= EFER_SVME;
@@ -466,7 +469,6 @@ int start_svm(void)
     printk("AMD SVM Extension is enabled for cpu %d.\n", cpu );
 
     /* Initialize the HSA for this core */
-    svm_globals[cpu].hsa = alloc_host_save_area();
     phys_hsa = (u64) virt_to_maddr( svm_globals[cpu].hsa ); 
     phys_hsa_lo = (u32) phys_hsa;
     phys_hsa_hi = (u32) (phys_hsa >> 32);    
index 3917650a4f918c3d654e6e171b447f204904068c..44c87335d69cc8f14d0cffcbc8b78f376e0463df 100644 (file)
@@ -139,18 +139,21 @@ static int construct_vmcb_controls(struct arch_svm_struct *arch_svm)
 
     /* The following is for I/O and MSR permision map */
     iopm = alloc_xenheap_pages(get_order_from_bytes(IOPM_SIZE));
-
-    ASSERT(iopm);
-    memset(iopm, 0xff, IOPM_SIZE);
-    clear_bit(PC_DEBUG_PORT, iopm);
+    if (iopm)
+    {
+        memset(iopm, 0xff, IOPM_SIZE);
+        clear_bit(PC_DEBUG_PORT, iopm);
+    }
     msrpm = alloc_xenheap_pages(get_order_from_bytes(MSRPM_SIZE));
-
-    ASSERT(msrpm);
-    memset(msrpm, 0xff, MSRPM_SIZE);
+    if (msrpm)
+        memset(msrpm, 0xff, MSRPM_SIZE);
 
     arch_svm->iopm = iopm;
     arch_svm->msrpm = msrpm;
 
+    if (! iopm || ! msrpm)
+        return 1;
+
     vmcb->iopm_base_pa = (u64) virt_to_maddr(iopm);
     vmcb->msrpm_base_pa = (u64) virt_to_maddr(msrpm);